/* Copyright (C) 2010 Luca Piccinelli
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <qt4/QtGui/QSlider>
#include <qt4/QtGui/QComboBox>
#include <sstream>

#include "common/pdl_visitors.h"
#include "exceptions/visitor_exceptions.h"

namespace NAMESPACE{

// ****** QtGuiPDLVisitor implementation ***************************************
QtGuiPDLVisitor::~QtGuiPDLVisitor(){}
QtGuiPDLVisitor::QtGuiPDLVisitor() : PDLElementVisitor(), layout(0){}
QtGuiPDLVisitor::QtGuiPDLVisitor(const QtGuiPDLVisitor& visitor) : PDLElementVisitor(visitor), layout(visitor.layout) {}
QtGuiPDLVisitor::QtGuiPDLVisitor(QLayout* _layout) : PDLElementVisitor(), layout(_layout) {}
const QtGuiPDLVisitor& QtGuiPDLVisitor::operator=(const QtGuiPDLVisitor& visitor){
    if (this == &visitor) return *this;
    PDLElementVisitor::operator =(visitor);
    layout = visitor.layout;
    return *this;
}
    
void QtGuiPDLVisitor::set_layout(QLayout* _layout){
    layout = _layout;
}
void QtGuiPDLVisitor::set_layout_address(long _layout_address){
    layout = reinterpret_cast<QLayout*>(_layout_address);
}

double QtGuiPDLVisitor::visitPDLRange(const PDLRange& range) throw(bad_visitor) {
    QSlider* qSlider = new QSlider(layout->parentWidget());
    qSlider->setProperty("scale", 1.0 / range.get_scale());
    qSlider->setMinimumWidth(100);
    qSlider->setRange(range.get_from(), range.get_to());    
    qSlider->setSingleStep(range.get_step());   
    qSlider->setOrientation(Qt::Horizontal);
    
    layout->addWidget(qSlider);
    
    return range.get_scale();
}
void QtGuiPDLVisitor::visitPDLComposite(const PDLComposite& composite) throw(bad_visitor) {
    QComboBox* combo = new QComboBox(layout->parentWidget());
    PDLComposite::const_iterator it = composite.begin(), end_it = composite.end();
    for(; it != end_it; it++){
        const PDLPair* el = dynamic_cast< const PDLPair*>(it.operator ->());
        if(el){
            combo->addItem(QString(el->get_label().c_str()), QVariant(el->get_value()));
        }else{
            const PDLLiteral* el = dynamic_cast< const PDLLiteral*>(it.operator ->());
            if(!el) {
                delete combo;
                throw bad_visitor("Invalid PDLElement inside PDLComposite");
            }
            
            std::stringstream ss; ss << el->get_value();
            combo->addItem(QString(ss.str().c_str()), QVariant(el->get_value()));
        }
        
        layout->addWidget(combo);
    }
}
// -----------------------------------------------------------------------------

}